/*
 * CouchFS.c
 * CouchFS
 *
 * Created by Mathieu ATTAL on 10/10/09.
 * Copyright 2009 __MyCompanyName__. All rights reserved.
 *
 */

#include <fuse.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include "REST.h"
#include <curl/curl.h>

static int
CouchFS_fgetattr(const char *path, struct stat *stbuf,
                  struct fuse_file_info *fi)
{
	memset(stbuf, 0, sizeof(struct stat));
  
	if (strcmp(path, "/") == 0)
	{ /* The root directory of our file system. */
		stbuf->st_mode = S_IFDIR | 0755;
		stbuf->st_nlink = 3;
    return 0;
	}
	return -ENOENT;
}

static int
CouchFS_getattr(const char *path, struct stat *stbuf)
{
  return CouchFS_fgetattr(path, stbuf, NULL);
}

static int
CouchFS_readlink(const char *path, char *buf, size_t size)
{
  return -ENOENT;
}

static int
CouchFS_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                 off_t offset, struct fuse_file_info *fi)
{
//	if (strcmp(path, "/") != 0) /* We only recognize the root directory. */
//		return -ENOENT;
  
	filler(buf, ".", NULL, 0);           /* Current directory (.)  */
	filler(buf, "..", NULL, 0);          /* Parent directory (..)  */

	//Get CoucheDb document in Path directory getdirrectory view
	//http://172.16.106.128:5984/couchfs/_view/tree/getdirectory?key="\/root\/toto"
	//http://172.16.106.128:5984/couchfs/_view/tree/getdirectory?key="\/root"
	
	return 0;
}

static int
CouchFS_mknod(const char *path, mode_t mode, dev_t rdev)
{
	return -ENOSYS;
}

static int
CouchFS_mkdir(const char *path, mode_t mode)
{
	return -ENOSYS;
}

static int
CouchFS_unlink(const char *path)
{
	return -ENOSYS;
}

static int
CouchFS_rmdir(const char *path)
{
	return -ENOSYS;
}

static int
CouchFS_symlink(const char *from, const char *to)
{
	return -ENOSYS;
}

static int
CouchFS_rename(const char *from, const char *to)
{
	return -ENOSYS;
}

static int
CouchFS_exchange(const char *path1, const char *path2, unsigned long options)
{
	return -ENOSYS;
}

static int
CouchFS_link(const char *from, const char *to)
{
	return -ENOSYS;
}

static int
CouchFS_fsetattr_x(const char *path, struct setattr_x *attr,
                    struct fuse_file_info *fi)
{
	return -ENOENT;
}

static int
CouchFS_setattr_x(const char *path, struct setattr_x *attr)
{
	return -ENOENT;
}

static int
CouchFS_getxtimes(const char *path, struct timespec *bkuptime,
                   struct timespec *crtime)
{
	return -ENOENT;
}

static int
CouchFS_create(const char *path, mode_t mode, struct fuse_file_info *fi)
{
	return -ENOSYS;
}

static int
CouchFS_open(const char *path, struct fuse_file_info *fi)
{
	return -ENOENT;
}

static int
CouchFS_read(const char *path, char *buf, size_t size, off_t offset,
              struct fuse_file_info *fi)
{
	return -ENOSYS;
}

static int
CouchFS_write(const char *path, const char *buf, size_t size,
               off_t offset, struct fuse_file_info *fi)
{
	return -ENOSYS;
}

static int
CouchFS_statfs(const char *path, struct statvfs *stbuf)
{
	memset(stbuf, 0, sizeof(*stbuf));
	stbuf->f_files = 2;  /* For . and .. in the root */
	return 0;
}

static int
CouchFS_flush(const char *path, struct fuse_file_info *fi)
{
	return 0;
}

static int
CouchFS_release(const char *path, struct fuse_file_info *fi)
{
	return 0;
}

static int
CouchFS_fsync(const char *path, int isdatasync, struct fuse_file_info *fi)
{
	return 0;
}

static int
CouchFS_setxattr(const char *path, const char *name, const char *value,
                  size_t size, int flags, uint32_t position)
{
	return -ENOTSUP;
}

static int
CouchFS_getxattr(const char *path, const char *name, char *value, size_t size,
                  uint32_t position)
{
	return -ENOATTR;
}

static int
CouchFS_listxattr(const char *path, char *list, size_t size)
{
	return 0;
}

static int
CouchFS_removexattr(const char *path, const char *name)
{
	return -ENOATTR;
}

void *
CouchFS_init(struct fuse_conn_info *conn)
{
	FUSE_ENABLE_XTIMES(conn);
	return NULL;
}

void
CouchFS_destroy(void *userdata)
{
  /* nothing */
}

struct fuse_operations CouchFS_operations =
{
	.init        = CouchFS_init,
	.destroy     = CouchFS_destroy,
	.getattr     = CouchFS_getattr,
	.fgetattr    = CouchFS_fgetattr,
/*  .access      = CouchFS_access, */
	.readlink    = CouchFS_readlink,
/*  .opendir     = CouchFS_opendir, */
	.readdir     = CouchFS_readdir,
/*  .releasedir  = CouchFS_releasedir, */
	.mknod       = CouchFS_mknod,
	.mkdir       = CouchFS_mkdir,
	.symlink     = CouchFS_symlink,
	.unlink      = CouchFS_unlink,
	.rmdir       = CouchFS_rmdir,
	.rename      = CouchFS_rename,
	.link        = CouchFS_link,
	.create      = CouchFS_create,
	.open        = CouchFS_open,
	.read        = CouchFS_read,
	.write       = CouchFS_write,
	.statfs      = CouchFS_statfs,
	.flush       = CouchFS_flush,
	.release     = CouchFS_release,
	.fsync       = CouchFS_fsync,
	.setxattr    = CouchFS_setxattr,
	.getxattr    = CouchFS_getxattr,
	.listxattr   = CouchFS_listxattr,
	.removexattr = CouchFS_removexattr,
	.exchange    = CouchFS_exchange,
	.getxtimes   = CouchFS_getxtimes,
	.setattr_x   = CouchFS_setattr_x,
	.fsetattr_x  = CouchFS_fsetattr_x,
};
